#include <iostream>
using namespace std;

/*
    父类的同名函数是虚函数和普通函数(非虚函数)的区别
     虚函数：编译器采用动态联编
     动态联编：编译器会严格按照赋值运算右边的类型来调用对应的同名函数

     普通函数(非虚函数)：编译器采用静态联编
     静态联编：编译器会严格按照赋值运算左边的类型来调用对应的同名函数

       父类eat()函数不是虚函数
           Animal a;
           Cat c;
           Animal &r=c; //父类的引用指向子类对象 
           r.eat(); //调用父类的eat()
           无论是指针还是引用，此时都以左边类型为准
       父类eat()函数是虚函数
           Animal a;
           Cat c;
           Animal &r=c; 
           r.eat(); //调用子类的eat()
           无论是指针还是引用，此时都以右边类型为准
*/

class Animal
{
public:
    virtual void eat()
    {
        cout << "animal eat" << endl;
    }
};

class Dog : public Animal
{
public:
    void eat()
    {
        cout << "dog eat" << endl;
    }
};

void showAnimalEat(Animal &a)
{
    a.eat();
}

int main()
{
    Animal a;
    Dog d;

    d.eat(); // 调用子类自己的eat

    showAnimalEat(d); // 如果没有使用虚函数，采用静态联编，看赋值运算左边的类型
    return 0;
}